//===----------------------------------------------------------------------===//
//
//                         CMU-DB Project (15-445/645)
//                         ***DO NO SHARE PUBLICLY***
//
// Identification: src/page/b_plus_tree_internal_page.cpp
//
// Copyright (c) 2018, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iostream>
#include <sstream>

#include "common/exception.h"
#include "storage/page/b_plus_tree_internal_page.h"

namespace bustub {
/*****************************************************************************
 * HELPER METHODS AND UTILITIES
 *****************************************************************************/
/*
 * Init method after creating a new internal page
 * Including set page type, set current size, set page id, set parent id and set
 * max page size
 */
INDEX_TEMPLATE_ARGUMENTS
void B_PLUS_TREE_INTERNAL_PAGE_TYPE::Init(page_id_t page_id, page_id_t parent_id, int max_size) {
  this->SetPageType(IndexPageType::INTERNAL_PAGE);
  this->SetSize(0);
  this->SetPageId(page_id);
  this->SetParentPageId(parent_id);
  this->SetMaxSize(max_size);
  // this->SetPageType(INTERNAL_PAGE);
  //页面大小为为4KB，head有24B
}
/*
 * Helper method to get/set the key associated with input "index"(a.k.a
 * array offset)
 */
INDEX_TEMPLATE_ARGUMENTS
auto B_PLUS_TREE_INTERNAL_PAGE_TYPE::KeyAt(int index) const -> KeyType {
  // replace with your own code
  KeyType key = this->array_[index].first;
  return key;
}

INDEX_TEMPLATE_ARGUMENTS
void B_PLUS_TREE_INTERNAL_PAGE_TYPE::SetKeyAt(const KeyType &key,int index) {
  this->array_[index].first=key;
}
INDEX_TEMPLATE_ARGUMENTS
void B_PLUS_TREE_INTERNAL_PAGE_TYPE::SetValueAt(const ValueType &value,int index) {
  this->array_[index].second=value;
}

/*
 * Helper method to get the value associated with input "index"(a.k.a array
 * offset)
 */
INDEX_TEMPLATE_ARGUMENTS
auto B_PLUS_TREE_INTERNAL_PAGE_TYPE::ValueAt(int index) const -> ValueType { 
  ValueType value = this->array_[index].second;
  return value;
}


INDEX_TEMPLATE_ARGUMENTS
auto B_PLUS_TREE_INTERNAL_PAGE_TYPE::SearchKey(const KeyType &key,const KeyComparator &comparator) -> int32_t{
  int32_t start = 1,end=this->GetSize();
  if(comparator(key,this->array_[end].first)==1) // 比最大的还大
    return end; // 注意：此时的end不能通过this->GetSize()
  for(int idx=start;idx<=end;idx++){
    if(comparator(this->array_[idx].first,key)==1||comparator(this->array_[idx].first,key)==0)//如果key小于节点中的当前值
      return idx;
  }
  return -1;
}

INDEX_TEMPLATE_ARGUMENTS
void B_PLUS_TREE_INTERNAL_PAGE_TYPE::CopyToTemp(MappingType*& desc){
  desc[0].second = this->ValueAt(0);
  for(int i=1;i<=this->GetSize();i++){
    desc[i].first = this->KeyAt(i);
    desc[i].second = this->ValueAt(i);
  }
}

INDEX_TEMPLATE_ARGUMENTS
void B_PLUS_TREE_INTERNAL_PAGE_TYPE::Erase(){
  memset(this->array_,0,this->GetMaxSize()*sizeof(MappingType));
  this->SetSize(0);
}

INDEX_TEMPLATE_ARGUMENTS
bool B_PLUS_TREE_INTERNAL_PAGE_TYPE::DeleteKV(const KeyType& key,const KeyComparator &comparator){
  // KeyComparator comp;
  int32_t idx = this->SearchKey(key,comparator);
  if(idx<0){
    std::cout<<"DeleteKV idx < 0"<<std::endl;
    return false;
  }
  // this->array_[idx]=
  //11.2 change < to <=
  for(int i=idx;i<=this->GetSize()-1;i++){
    this->array_[i]=this->array_[i+1];
  }
  // this->size_--;
  this->SetSize(this->GetSize()-1);
  return true;
}

// valuetype for internalNode should be page id_t
template class BPlusTreeInternalPage<GenericKey<4>, page_id_t, GenericComparator<4>>;
template class BPlusTreeInternalPage<GenericKey<8>, page_id_t, GenericComparator<8>>;
template class BPlusTreeInternalPage<GenericKey<16>, page_id_t, GenericComparator<16>>;
template class BPlusTreeInternalPage<GenericKey<32>, page_id_t, GenericComparator<32>>;
template class BPlusTreeInternalPage<GenericKey<64>, page_id_t, GenericComparator<64>>;
}  // namespace bustub
